package com.lv.fast.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lv.fast.DO.SysRoleDO;
import com.lv.fast.DTO.SysMenuDTO;
import com.lv.fast.DTO.SysRoleDTO;
import com.lv.fast.DTO.SysRolePageQuery;
import com.lv.fast.constant.UserConstant;
import com.lv.fast.dao.SysRoleDao;
import com.lv.fast.dao.SysUserDao;
import com.lv.fast.service.SysMenuService;
import com.lv.fast.service.SysRoleService;
import com.lv.fast.util.Assert;
import com.lv.fast.util.PageUtil;
import com.lv.fast.util.QueryWrapperUtil;
import com.lv.fast.util.SysUserUtil;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.LinkedHashSet;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Description
 * @Author jie.lv
 */
@Service
@AllArgsConstructor
public class SysRoleServiceImpl implements SysRoleService {

    private final SysRoleDao sysRoleDao;

    private final SysUserDao sysUserDao;

    private final SysMenuService sysMenuService;

    @Override
    public LinkedHashSet<SysRoleDTO> listUserRoleByUserId(String userId, boolean isContainsMenus){
        Assert.assertNotNull(userId, "获取用户角色列表时用户Id不能为空");
        LinkedHashSet<SysRoleDTO> roles = sysRoleDao.listUserRoleByUserId(userId);
        if (CollectionUtil.isEmpty(roles)){
            //写入默认角色
            sysUserDao.batchInsertUserRole(userId, Stream.of(UserConstant.DEFAULT_ROLE_ID).collect(Collectors.toSet()));
        }
        if (isContainsMenus){
            boolean isAdmin = roles.stream().map(SysRoleDTO::getId).collect(Collectors.toSet()).contains(UserConstant.SUPER_ADMINISTRATOR_ROLE_ID);
            if (isAdmin){
                LinkedHashSet<SysMenuDTO> sysMenuDTOS = sysMenuService.listAll();
                roles.forEach(sysRoleDTO -> {
                    if (sysRoleDTO.getId().equals(UserConstant.SUPER_ADMINISTRATOR_ROLE_ID)){
                        sysRoleDTO.setMenus(sysMenuDTOS);
                    }
                });
            }else {
                roles = sysRoleDao.listUserRoleMenuByUserId(userId);
            }
        }
        return roles;
    }

    @Override
    public IPage<SysRoleDTO> list(SysRolePageQuery pageQuery){
        QueryWrapper<SysRoleDO> wrapper = QueryWrapperUtil.getPageQueryWrapper(pageQuery, "role_name");
        Page<SysRoleDTO> page = sysRoleDao.selectPage(PageUtil.getPage(pageQuery), wrapper);
        return page;
    }

    @Override
    public SysRoleDTO get(String id){
        Assert.assertNotNull(id, "角色Id不能为空");
        SysRoleDO sysRoleDO = sysRoleDao.selectById(id);
        SysRoleDTO sysRoleDTO = BeanUtil.copyProperties(sysRoleDO, SysRoleDTO.class);
        return sysRoleDTO;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public boolean update(SysRoleDTO sysRoleDTO){
        SysRoleDO sysRoleDO = BeanUtil.copyProperties(sysRoleDTO, SysRoleDO.class);
        String roleId = sysRoleDO.getId();
        Assert.assertNotNull(roleId, "角色Id不能为空");
        LinkedHashSet<SysMenuDTO> menus = sysRoleDTO.getMenus();
        if (CollectionUtil.isNotEmpty(menus)){
            //删除所有菜单
            sysRoleDao.deleteRoleMenuByRoleId(roleId);
            //新增菜单
            sysRoleDao.batchInsertRoleMenu(roleId, menus);
        }
        sysRoleDO.setUpdatedBy(SysUserUtil.getCurrentLoginUserId());
        sysRoleDao.updateById(sysRoleDO);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public boolean add(SysRoleDTO sysRoleDTO){
        Assert.assertNotNull(sysRoleDTO, "角色对象不能为空");
        SysRoleDO sysRoleDO = BeanUtil.copyProperties(sysRoleDTO, SysRoleDO.class);
        String id = String.valueOf(IdWorker.getId());
        sysRoleDO.setId(id);
        LinkedHashSet<SysMenuDTO> menus = sysRoleDTO.getMenus();
        if (CollectionUtil.isNotEmpty(menus)){
            //新增角色菜单
            sysRoleDao.batchInsertRoleMenu(id, menus);
        }
        sysRoleDO.setCreatedBy(SysUserUtil.getCurrentLoginUserId());
        sysRoleDO.setUpdatedBy(SysUserUtil.getCurrentLoginUserId());
        sysRoleDao.insert(sysRoleDO);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public boolean delete(String roleId){
        Assert.assertNotNull(roleId, "角色Id不能为空");
        // 删除用户角色关系
        sysRoleDao.deleteUserRoleByRoleId(roleId);
        // 删除角色权限关系
        sysRoleDao.deleteRoleMenuByRoleId(roleId);
        // 删除角色
        sysRoleDao.deleteById(roleId);
        return true;
    }
}
